<?php

require_once 'includes/php.php';
class Url
{
	static public $url_components = array('scheme', 'host', 'port', 'user', 'pass', 'path', 'query', 'fragment');

	public function __construct ($url=NULL)
	{
		if ($url) {
			$this->fromString($url);
		}
	} // end of __construct

	public function fromString ($str)
	{
		unset($this->params);

		$us = parse_url($str);
		foreach (self::$url_components as $k) {
			$setter = 'set'.$k;
			if (isset($us[$k])) {
				$value = $us[$k];
			} else {
				$value = NULL;
			}
			$this->$setter($value);
		}
		return $this;
	} // end of function fromString
	public function createFromString ($str)
	{
		$o = new Url();
		return $o->fromString($str);
	} // end of function newFromString

	public function setScheme ($v)
	{
		$this->scheme = $v;
		return $this;
	} // end of function setScheme
	public function getScheme ()
	{
		return $this->scheme;
	} // end of function getScheme

	public function setHost ($v)
	{
		$this->host = $v;
		return $this;
	} // end of function setHost
	public function getHost ()
	{
		return $this->host;
	} // end of function getHost

	public function setPort ($v)
	{
		$this->port = $v;
		return $this;
	} // end of function setPort
	public function getPort ()
	{
		return $this->port;
	} // end of function getPort

	public function setUser ($v)
	{
		$this->user = $v;
		return $this;
	} // end of function setUser
	public function getUser ()
	{
		return $this->user;
	} // end of function getUser

	public function setPass ($v)
	{
		$this->pass = $v;
		return $this;
	} // end of function setPass
	public function getPass ()
	{
		return $this->pass;
	} // end of function getPass

	public function setPath ($v)
	{
		$this->path = $v;
		return $this;
	} // end of function setPath
	public function getPath ()
	{
		return $this->path;
	} // end of function getPath

	public function setQuery ($v)
	{
		$this->query = $v;
		unset($this->params);
		return $this;
	} // end of function setQuery
	public function getQuery ()
	{
		if (isset($this->params)) {
			$query = http_build_query($this->params);
		} else {
			$query = $this->query;
		}
		return $query;
	} // end of function getQuery

	public function setFragment ($v)
	{
		$this->fragment = $v;
		return $this;
	} // end of function setFragment
	public function getFragment ()
	{
		return $this->fragment;
	} // end of function getFragment

	public function setParam ($name, $v)
	{
		if (!isset($this->params)) {
			if (isset($this->query)) {
				php_parse_str($this->query, $this->params);
			} else {
				$this->params = array();
			}
		}
		if (isset($v)) {
			$this->params[$name] = $v;
		} else {
			unset($this->params[$name]);
		}
		return $this;
	} // end of function setParam
	public function getParam ($name, $default=NULL)
	{
		if (!isset($this->params)) {
			if (isset($this->query)) {
				php_parse_str($this->query, $this->params);
			}
		}
		return (is_array($this->params) && array_key_exists($name, $this->params)) 
			? $this->params[$name] 
			: $default;
	} // end of function getParam
	public function unsetParam ($name)
	{
		$this->setParam($name, NULL);
		return $this;
	} // end of function unsetParam

	public function setParams (array $params)
	{
		foreach ($params as $k=>$v) { 
			$this->setParam($k, $v);
		}
		return $this;
	} // end of function setParams

	public function getUrl ()
	{
		$scheme = $this->getScheme();
		$host   = $this->getHost();
		$port   = $this->getPort();
		$user   = $this->getUser();
		$pass   = $this->getPass();
		return 
			  ($scheme? $scheme. '://' : $scheme)
			. ($user  ? $user . ($pass ? ':' . $pass : '') . '@'  : '') 
			. $host
			. ($port  ? ':'. $port  : '') 
			. $this->getHref()
			;
	} // end of function getUrl
	public function getHref ()
	{
		$path   = $this->getPath();
		$query  = $this->getQuery();
		$frag   = $this->getFragment();
		return $path 
			. ($query ? '?'. $query : '') 
			. ($frag  ? '#'. $frag  : '')
			;
	} // end of function getUrl

	public function __toString ()
	{
		return $this->getUrl();
	} // end of function _toString

}

